fix mkshort unique (#1168)
authortsteven4 <13596209+tsteven4@users.noreply.github.com>
Fri, 1 Sep 2023 17:00:45 +0000 (11:00 -0600)
committerGitHub <noreply@github.com>
Fri, 1 Sep 2023 17:00:45 +0000 (11:00 -0600)
* fix mkshort unique.

1. we were off by one when deciding if we could just concatentate
the generated suffix to the name, failing to use the last available
character.
2. when attempting to copy the generated suffix to a presumably
shortened name, and the generated suffix was longer than the name,
the target of the copy was outside the name buffer.  In the common
case that the rank of size_t was greater than the rank of int, the
target was well beyond the end of name, not before as one would expect
with signed arithmetic.

With the new algorithm when the target length is insufficient to
fit both the name and the suffix we will only truncate the name as
required to fit the truncated name and the complete suffix in the
target length(as opposed to the original length of the name).
We fatal if this is not possible.

Add a test case to exercise the make unique code.

* fix reference mode.

* add notes for future enhancements

* fix testcase cut and paste booboo

* refactor mkshort input from char* to QByteArray.

defs.h
garmin.cc
mkshort.cc
reference/mkshort.csv [new file with mode: 0644]
reference/mkshort.style [new file with mode: 0644]
reference/mkshort3.log [new file with mode: 0644]
reference/mkshort4.csv [new file with mode: 0644]
reference/mkshort5.csv [new file with mode: 0644]
reference/mkshort6.csv [new file with mode: 0644]
testo.d/mkshort.test [new file with mode: 0644]

diff --git a/defs.h b/defs.h
index 692742a261d390b58bcd3d8201bd4006bc6a872c..59529761a16cebb09cfab5aac8f597327af962e6 100644 (file)
--- a/defs.h
+++ b/defs.h
@@ -847,7 +847,7 @@ using ff_readposn = Waypoint* (*)(posn_status*);
 struct mkshort_handle_imp; // forward declare, definition in mkshort.cc
 using short_handle = mkshort_handle_imp*;
 
-QByteArray mkshort(short_handle, const char*, bool);
+QByteArray mkshort(short_handle, const QByteArray&, bool);
 QString mkshort(short_handle, const QString&);
 short_handle mkshort_new_handle();
 QString mkshort_from_wpt(short_handle h, const Waypoint* wpt);
index 8bf801052b559fb34308d8880f60c4c37ff83319..976033291427add693c3f69ff455cd6fd29413e9 100644 (file)
--- a/garmin.cc
+++ b/garmin.cc
@@ -890,8 +890,8 @@ waypoint_prepare()
      */
     QByteArray ident = mkshort(mkshort_handle,
                                global_opts.synthesize_shortnames ?
-                               str_from_unicode(src).constData() :
-                               str_from_unicode(wpt->shortname).constData(),
+                               str_from_unicode(src) :
+                               str_from_unicode(wpt->shortname),
                                false);
     /* Should not be a strcpy as 'ident' isn't really a C string,
      * but rather a garmin "fixed length" buffer that's padded
index ec78bffff76942a5a1bf6cca508c0e2467e59176..ef6c4b69748c64d17f59209246fba40ec797d186 100644 (file)
@@ -19,8 +19,9 @@
 
  */
 
+#include <cassert>     // for assert
 #include <cctype>      // for isspace, toupper, isdigit
-#include <cstdio>      // for snprintf, size_t
+#include <climits>     // for INT_MAX
 #include <cstring>     // for strlen, memmove, strchr, strcpy, strncmp, strcat, strncpy
 
 #include <QByteArray>  // for QByteArray
@@ -49,7 +50,7 @@ class ShortNameKey;
 using ShortNameHash = QHash<ShortNameKey, uniq_shortname*>;
 class ShortNameKey {
 public:
-  ShortNameKey(char* name) : shortname(name) {} /* converting constructor */
+  ShortNameKey(const QByteArray& name) : shortname(name) {} /* converting constructor */
 
   friend qhash_result_t qHash(const ShortNameKey &key, qhash_result_t seed = 0) noexcept
   {
@@ -109,7 +110,7 @@ mkshort_new_handle()
 
 static
 uniq_shortname*
-is_unique(mkshort_handle_imp* h, char* name)
+is_unique(mkshort_handle_imp* h, const QByteArray& name)
 {
   if (h->namelist.contains(name)) {
     return h->namelist.value(name);
@@ -119,34 +120,38 @@ is_unique(mkshort_handle_imp* h, char* name)
 
 static
 void
-add_to_hashlist(mkshort_handle_imp* h, char* name)
+add_to_hashlist(mkshort_handle_imp* h, const QByteArray& name)
 {
   h->namelist.insert(name, new uniq_shortname);
 }
 
-char*
-mkshort_add_to_list(mkshort_handle_imp* h, char* name)
+static
+void
+mkshort_add_to_list(mkshort_handle_imp* h, QByteArray& name)
 {
-  uniq_shortname* s;
+  static_assert(!std::is_signed<decltype(h->target_len)>::value,
+                "simplify the following logic if target length is signed.");
+  assert(h->target_len <= INT_MAX);
+  int target_len = h->target_len;
 
+  uniq_shortname* s;
   while ((s = is_unique(h, name))) {
-    char tbuf[13];
-    size_t l = strlen(name);
 
-    s->conflictctr++;
+    QByteArray suffix(".");
+    suffix.append(QByteArray::number(++s->conflictctr));
 
-    int dl = snprintf(tbuf, sizeof(tbuf), ".%d", s->conflictctr);
-
-    if (l + dl < h->target_len) {
-      name = (char*) xrealloc(name, l + dl + 1);
-      strcat(name, tbuf);
+    if (name.size() + suffix.size() <= target_len) {
+      name.append(suffix);
+    } else if (suffix.size() <= target_len) {
+      // FIXME: utf8 => grapheme truncate
+      name.truncate(target_len - suffix.size());
+      name.append(suffix);
     } else {
-      strcpy(&name[l-dl], tbuf);
+      fatal("mkshort failure, the specified short length is insufficient.\n");
     }
   }
 
   add_to_hashlist(h, name);
-  return name;
 }
 
 void
@@ -249,7 +254,9 @@ void
 setshort_length(short_handle h, int l)
 {
   auto* hdl = (mkshort_handle_imp*) h;
-  if (l == 0) {
+  if (l < 0) {
+    fatal("mkshort: short length must be non-negative.\n");
+  } else if (l == 0) {
     hdl->target_len = default_target_len;
   } else {
     hdl->target_len = l;
@@ -354,7 +361,7 @@ setshort_mustuniq(short_handle h, int i)
 }
 
 QByteArray
-mkshort(short_handle h, const char* istring, bool is_utf8)
+mkshort(short_handle h, const QByteArray& istring, bool is_utf8)
 {
   char* ostring;
   char* tstring;
@@ -370,7 +377,7 @@ mkshort(short_handle h, const char* istring, bool is_utf8)
     result.remove(QChar::ReplacementCharacter);
     ostring = xstrdup(result.toUtf8().constData());
   } else {
-    ostring = xstrdup(istring);
+    ostring = xstrdup(istring.constData());
   }
 
   /*
@@ -555,18 +562,18 @@ mkshort(short_handle h, const char* istring, bool is_utf8)
     ostring = xstrdup(hdl->defname);
   }
 
-  if (hdl->must_uniq) {
-    ostring = mkshort_add_to_list(hdl, ostring);
-  }
   QByteArray rval(ostring);
   xfree(ostring);
+  if (hdl->must_uniq) {
+    mkshort_add_to_list(hdl, rval);
+  }
   return rval;
 }
 
 QString
 mkshort(short_handle h, const QString& istring)
 {
-  return mkshort(h, CSTR(istring), true);
+  return mkshort(h, istring.toUtf8(), true);
 }
 
 /*
diff --git a/reference/mkshort.csv b/reference/mkshort.csv
new file mode 100644 (file)
index 0000000..c11185d
--- /dev/null
@@ -0,0 +1,151 @@
+lat,lon,name\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
+0,0,wp\r
diff --git a/reference/mkshort.style b/reference/mkshort.style
new file mode 100644 (file)
index 0000000..52ef14f
--- /dev/null
@@ -0,0 +1,17 @@
+# gpsbabel XCSV style file
+#
+DESCRIPTION    Comma separated values
+SHORTLEN       4
+#
+# FILE LAYOUT DEFINITIIONS:
+#
+FIELD_ENCLOSER    DOUBLEQUOTE
+FIELD_DELIMITER                COMMASPACE
+RECORD_DELIMITER       NEWLINE
+BADCHARS               COMMA
+#
+# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:
+#
+IFIELD  LAT_DECIMAL, "", "%8.5f"
+IFIELD  LON_DECIMAL, "", "%8.5f"
+IFIELD SHORTNAME, "", "%s"
diff --git a/reference/mkshort3.log b/reference/mkshort3.log
new file mode 100644 (file)
index 0000000..38059e1
--- /dev/null
@@ -0,0 +1 @@
+mkshort failure, the specified short length is insufficient.
diff --git a/reference/mkshort4.csv b/reference/mkshort4.csv
new file mode 100644 (file)
index 0000000..831e6b6
--- /dev/null
@@ -0,0 +1,150 @@
+"0.00000", "0.00000", "wp"
+"0.00000", "0.00000", "wp.1"
+"0.00000", "0.00000", "wp.2"
+"0.00000", "0.00000", "wp.3"
+"0.00000", "0.00000", "wp.4"
+"0.00000", "0.00000", "wp.5"
+"0.00000", "0.00000", "wp.6"
+"0.00000", "0.00000", "wp.7"
+"0.00000", "0.00000", "wp.8"
+"0.00000", "0.00000", "wp.9"
+"0.00000", "0.00000", "w.10"
+"0.00000", "0.00000", "w.11"
+"0.00000", "0.00000", "w.12"
+"0.00000", "0.00000", "w.13"
+"0.00000", "0.00000", "w.14"
+"0.00000", "0.00000", "w.15"
+"0.00000", "0.00000", "w.16"
+"0.00000", "0.00000", "w.17"
+"0.00000", "0.00000", "w.18"
+"0.00000", "0.00000", "w.19"
+"0.00000", "0.00000", "w.20"
+"0.00000", "0.00000", "w.21"
+"0.00000", "0.00000", "w.22"
+"0.00000", "0.00000", "w.23"
+"0.00000", "0.00000", "w.24"
+"0.00000", "0.00000", "w.25"
+"0.00000", "0.00000", "w.26"
+"0.00000", "0.00000", "w.27"
+"0.00000", "0.00000", "w.28"
+"0.00000", "0.00000", "w.29"
+"0.00000", "0.00000", "w.30"
+"0.00000", "0.00000", "w.31"
+"0.00000", "0.00000", "w.32"
+"0.00000", "0.00000", "w.33"
+"0.00000", "0.00000", "w.34"
+"0.00000", "0.00000", "w.35"
+"0.00000", "0.00000", "w.36"
+"0.00000", "0.00000", "w.37"
+"0.00000", "0.00000", "w.38"
+"0.00000", "0.00000", "w.39"
+"0.00000", "0.00000", "w.40"
+"0.00000", "0.00000", "w.41"
+"0.00000", "0.00000", "w.42"
+"0.00000", "0.00000", "w.43"
+"0.00000", "0.00000", "w.44"
+"0.00000", "0.00000", "w.45"
+"0.00000", "0.00000", "w.46"
+"0.00000", "0.00000", "w.47"
+"0.00000", "0.00000", "w.48"
+"0.00000", "0.00000", "w.49"
+"0.00000", "0.00000", "w.50"
+"0.00000", "0.00000", "w.51"
+"0.00000", "0.00000", "w.52"
+"0.00000", "0.00000", "w.53"
+"0.00000", "0.00000", "w.54"
+"0.00000", "0.00000", "w.55"
+"0.00000", "0.00000", "w.56"
+"0.00000", "0.00000", "w.57"
+"0.00000", "0.00000", "w.58"
+"0.00000", "0.00000", "w.59"
+"0.00000", "0.00000", "w.60"
+"0.00000", "0.00000", "w.61"
+"0.00000", "0.00000", "w.62"
+"0.00000", "0.00000", "w.63"
+"0.00000", "0.00000", "w.64"
+"0.00000", "0.00000", "w.65"
+"0.00000", "0.00000", "w.66"
+"0.00000", "0.00000", "w.67"
+"0.00000", "0.00000", "w.68"
+"0.00000", "0.00000", "w.69"
+"0.00000", "0.00000", "w.70"
+"0.00000", "0.00000", "w.71"
+"0.00000", "0.00000", "w.72"
+"0.00000", "0.00000", "w.73"
+"0.00000", "0.00000", "w.74"
+"0.00000", "0.00000", "w.75"
+"0.00000", "0.00000", "w.76"
+"0.00000", "0.00000", "w.77"
+"0.00000", "0.00000", "w.78"
+"0.00000", "0.00000", "w.79"
+"0.00000", "0.00000", "w.80"
+"0.00000", "0.00000", "w.81"
+"0.00000", "0.00000", "w.82"
+"0.00000", "0.00000", "w.83"
+"0.00000", "0.00000", "w.84"
+"0.00000", "0.00000", "w.85"
+"0.00000", "0.00000", "w.86"
+"0.00000", "0.00000", "w.87"
+"0.00000", "0.00000", "w.88"
+"0.00000", "0.00000", "w.89"
+"0.00000", "0.00000", "w.90"
+"0.00000", "0.00000", "w.91"
+"0.00000", "0.00000", "w.92"
+"0.00000", "0.00000", "w.93"
+"0.00000", "0.00000", "w.94"
+"0.00000", "0.00000", "w.95"
+"0.00000", "0.00000", "w.96"
+"0.00000", "0.00000", "w.97"
+"0.00000", "0.00000", "w.98"
+"0.00000", "0.00000", "w.99"
+"0.00000", "0.00000", ".100"
+"0.00000", "0.00000", ".101"
+"0.00000", "0.00000", ".102"
+"0.00000", "0.00000", ".103"
+"0.00000", "0.00000", ".104"
+"0.00000", "0.00000", ".105"
+"0.00000", "0.00000", ".106"
+"0.00000", "0.00000", ".107"
+"0.00000", "0.00000", ".108"
+"0.00000", "0.00000", ".109"
+"0.00000", "0.00000", ".110"
+"0.00000", "0.00000", ".111"
+"0.00000", "0.00000", ".112"
+"0.00000", "0.00000", ".113"
+"0.00000", "0.00000", ".114"
+"0.00000", "0.00000", ".115"
+"0.00000", "0.00000", ".116"
+"0.00000", "0.00000", ".117"
+"0.00000", "0.00000", ".118"
+"0.00000", "0.00000", ".119"
+"0.00000", "0.00000", ".120"
+"0.00000", "0.00000", ".121"
+"0.00000", "0.00000", ".122"
+"0.00000", "0.00000", ".123"
+"0.00000", "0.00000", ".124"
+"0.00000", "0.00000", ".125"
+"0.00000", "0.00000", ".126"
+"0.00000", "0.00000", ".127"
+"0.00000", "0.00000", ".128"
+"0.00000", "0.00000", ".129"
+"0.00000", "0.00000", ".130"
+"0.00000", "0.00000", ".131"
+"0.00000", "0.00000", ".132"
+"0.00000", "0.00000", ".133"
+"0.00000", "0.00000", ".134"
+"0.00000", "0.00000", ".135"
+"0.00000", "0.00000", ".136"
+"0.00000", "0.00000", ".137"
+"0.00000", "0.00000", ".138"
+"0.00000", "0.00000", ".139"
+"0.00000", "0.00000", ".140"
+"0.00000", "0.00000", ".141"
+"0.00000", "0.00000", ".142"
+"0.00000", "0.00000", ".143"
+"0.00000", "0.00000", ".144"
+"0.00000", "0.00000", ".145"
+"0.00000", "0.00000", ".146"
+"0.00000", "0.00000", ".147"
+"0.00000", "0.00000", ".148"
+"0.00000", "0.00000", ".149"
diff --git a/reference/mkshort5.csv b/reference/mkshort5.csv
new file mode 100644 (file)
index 0000000..e87dca0
--- /dev/null
@@ -0,0 +1,150 @@
+"0.00000", "0.00000", "wp"
+"0.00000", "0.00000", "wp.1"
+"0.00000", "0.00000", "wp.2"
+"0.00000", "0.00000", "wp.3"
+"0.00000", "0.00000", "wp.4"
+"0.00000", "0.00000", "wp.5"
+"0.00000", "0.00000", "wp.6"
+"0.00000", "0.00000", "wp.7"
+"0.00000", "0.00000", "wp.8"
+"0.00000", "0.00000", "wp.9"
+"0.00000", "0.00000", "wp.10"
+"0.00000", "0.00000", "wp.11"
+"0.00000", "0.00000", "wp.12"
+"0.00000", "0.00000", "wp.13"
+"0.00000", "0.00000", "wp.14"
+"0.00000", "0.00000", "wp.15"
+"0.00000", "0.00000", "wp.16"
+"0.00000", "0.00000", "wp.17"
+"0.00000", "0.00000", "wp.18"
+"0.00000", "0.00000", "wp.19"
+"0.00000", "0.00000", "wp.20"
+"0.00000", "0.00000", "wp.21"
+"0.00000", "0.00000", "wp.22"
+"0.00000", "0.00000", "wp.23"
+"0.00000", "0.00000", "wp.24"
+"0.00000", "0.00000", "wp.25"
+"0.00000", "0.00000", "wp.26"
+"0.00000", "0.00000", "wp.27"
+"0.00000", "0.00000", "wp.28"
+"0.00000", "0.00000", "wp.29"
+"0.00000", "0.00000", "wp.30"
+"0.00000", "0.00000", "wp.31"
+"0.00000", "0.00000", "wp.32"
+"0.00000", "0.00000", "wp.33"
+"0.00000", "0.00000", "wp.34"
+"0.00000", "0.00000", "wp.35"
+"0.00000", "0.00000", "wp.36"
+"0.00000", "0.00000", "wp.37"
+"0.00000", "0.00000", "wp.38"
+"0.00000", "0.00000", "wp.39"
+"0.00000", "0.00000", "wp.40"
+"0.00000", "0.00000", "wp.41"
+"0.00000", "0.00000", "wp.42"
+"0.00000", "0.00000", "wp.43"
+"0.00000", "0.00000", "wp.44"
+"0.00000", "0.00000", "wp.45"
+"0.00000", "0.00000", "wp.46"
+"0.00000", "0.00000", "wp.47"
+"0.00000", "0.00000", "wp.48"
+"0.00000", "0.00000", "wp.49"
+"0.00000", "0.00000", "wp.50"
+"0.00000", "0.00000", "wp.51"
+"0.00000", "0.00000", "wp.52"
+"0.00000", "0.00000", "wp.53"
+"0.00000", "0.00000", "wp.54"
+"0.00000", "0.00000", "wp.55"
+"0.00000", "0.00000", "wp.56"
+"0.00000", "0.00000", "wp.57"
+"0.00000", "0.00000", "wp.58"
+"0.00000", "0.00000", "wp.59"
+"0.00000", "0.00000", "wp.60"
+"0.00000", "0.00000", "wp.61"
+"0.00000", "0.00000", "wp.62"
+"0.00000", "0.00000", "wp.63"
+"0.00000", "0.00000", "wp.64"
+"0.00000", "0.00000", "wp.65"
+"0.00000", "0.00000", "wp.66"
+"0.00000", "0.00000", "wp.67"
+"0.00000", "0.00000", "wp.68"
+"0.00000", "0.00000", "wp.69"
+"0.00000", "0.00000", "wp.70"
+"0.00000", "0.00000", "wp.71"
+"0.00000", "0.00000", "wp.72"
+"0.00000", "0.00000", "wp.73"
+"0.00000", "0.00000", "wp.74"
+"0.00000", "0.00000", "wp.75"
+"0.00000", "0.00000", "wp.76"
+"0.00000", "0.00000", "wp.77"
+"0.00000", "0.00000", "wp.78"
+"0.00000", "0.00000", "wp.79"
+"0.00000", "0.00000", "wp.80"
+"0.00000", "0.00000", "wp.81"
+"0.00000", "0.00000", "wp.82"
+"0.00000", "0.00000", "wp.83"
+"0.00000", "0.00000", "wp.84"
+"0.00000", "0.00000", "wp.85"
+"0.00000", "0.00000", "wp.86"
+"0.00000", "0.00000", "wp.87"
+"0.00000", "0.00000", "wp.88"
+"0.00000", "0.00000", "wp.89"
+"0.00000", "0.00000", "wp.90"
+"0.00000", "0.00000", "wp.91"
+"0.00000", "0.00000", "wp.92"
+"0.00000", "0.00000", "wp.93"
+"0.00000", "0.00000", "wp.94"
+"0.00000", "0.00000", "wp.95"
+"0.00000", "0.00000", "wp.96"
+"0.00000", "0.00000", "wp.97"
+"0.00000", "0.00000", "wp.98"
+"0.00000", "0.00000", "wp.99"
+"0.00000", "0.00000", "w.100"
+"0.00000", "0.00000", "w.101"
+"0.00000", "0.00000", "w.102"
+"0.00000", "0.00000", "w.103"
+"0.00000", "0.00000", "w.104"
+"0.00000", "0.00000", "w.105"
+"0.00000", "0.00000", "w.106"
+"0.00000", "0.00000", "w.107"
+"0.00000", "0.00000", "w.108"
+"0.00000", "0.00000", "w.109"
+"0.00000", "0.00000", "w.110"
+"0.00000", "0.00000", "w.111"
+"0.00000", "0.00000", "w.112"
+"0.00000", "0.00000", "w.113"
+"0.00000", "0.00000", "w.114"
+"0.00000", "0.00000", "w.115"
+"0.00000", "0.00000", "w.116"
+"0.00000", "0.00000", "w.117"
+"0.00000", "0.00000", "w.118"
+"0.00000", "0.00000", "w.119"
+"0.00000", "0.00000", "w.120"
+"0.00000", "0.00000", "w.121"
+"0.00000", "0.00000", "w.122"
+"0.00000", "0.00000", "w.123"
+"0.00000", "0.00000", "w.124"
+"0.00000", "0.00000", "w.125"
+"0.00000", "0.00000", "w.126"
+"0.00000", "0.00000", "w.127"
+"0.00000", "0.00000", "w.128"
+"0.00000", "0.00000", "w.129"
+"0.00000", "0.00000", "w.130"
+"0.00000", "0.00000", "w.131"
+"0.00000", "0.00000", "w.132"
+"0.00000", "0.00000", "w.133"
+"0.00000", "0.00000", "w.134"
+"0.00000", "0.00000", "w.135"
+"0.00000", "0.00000", "w.136"
+"0.00000", "0.00000", "w.137"
+"0.00000", "0.00000", "w.138"
+"0.00000", "0.00000", "w.139"
+"0.00000", "0.00000", "w.140"
+"0.00000", "0.00000", "w.141"
+"0.00000", "0.00000", "w.142"
+"0.00000", "0.00000", "w.143"
+"0.00000", "0.00000", "w.144"
+"0.00000", "0.00000", "w.145"
+"0.00000", "0.00000", "w.146"
+"0.00000", "0.00000", "w.147"
+"0.00000", "0.00000", "w.148"
+"0.00000", "0.00000", "w.149"
diff --git a/reference/mkshort6.csv b/reference/mkshort6.csv
new file mode 100644 (file)
index 0000000..230f755
--- /dev/null
@@ -0,0 +1,150 @@
+"0.00000", "0.00000", "wp"
+"0.00000", "0.00000", "wp.1"
+"0.00000", "0.00000", "wp.2"
+"0.00000", "0.00000", "wp.3"
+"0.00000", "0.00000", "wp.4"
+"0.00000", "0.00000", "wp.5"
+"0.00000", "0.00000", "wp.6"
+"0.00000", "0.00000", "wp.7"
+"0.00000", "0.00000", "wp.8"
+"0.00000", "0.00000", "wp.9"
+"0.00000", "0.00000", "wp.10"
+"0.00000", "0.00000", "wp.11"
+"0.00000", "0.00000", "wp.12"
+"0.00000", "0.00000", "wp.13"
+"0.00000", "0.00000", "wp.14"
+"0.00000", "0.00000", "wp.15"
+"0.00000", "0.00000", "wp.16"
+"0.00000", "0.00000", "wp.17"
+"0.00000", "0.00000", "wp.18"
+"0.00000", "0.00000", "wp.19"
+"0.00000", "0.00000", "wp.20"
+"0.00000", "0.00000", "wp.21"
+"0.00000", "0.00000", "wp.22"
+"0.00000", "0.00000", "wp.23"
+"0.00000", "0.00000", "wp.24"
+"0.00000", "0.00000", "wp.25"
+"0.00000", "0.00000", "wp.26"
+"0.00000", "0.00000", "wp.27"
+"0.00000", "0.00000", "wp.28"
+"0.00000", "0.00000", "wp.29"
+"0.00000", "0.00000", "wp.30"
+"0.00000", "0.00000", "wp.31"
+"0.00000", "0.00000", "wp.32"
+"0.00000", "0.00000", "wp.33"
+"0.00000", "0.00000", "wp.34"
+"0.00000", "0.00000", "wp.35"
+"0.00000", "0.00000", "wp.36"
+"0.00000", "0.00000", "wp.37"
+"0.00000", "0.00000", "wp.38"
+"0.00000", "0.00000", "wp.39"
+"0.00000", "0.00000", "wp.40"
+"0.00000", "0.00000", "wp.41"
+"0.00000", "0.00000", "wp.42"
+"0.00000", "0.00000", "wp.43"
+"0.00000", "0.00000", "wp.44"
+"0.00000", "0.00000", "wp.45"
+"0.00000", "0.00000", "wp.46"
+"0.00000", "0.00000", "wp.47"
+"0.00000", "0.00000", "wp.48"
+"0.00000", "0.00000", "wp.49"
+"0.00000", "0.00000", "wp.50"
+"0.00000", "0.00000", "wp.51"
+"0.00000", "0.00000", "wp.52"
+"0.00000", "0.00000", "wp.53"
+"0.00000", "0.00000", "wp.54"
+"0.00000", "0.00000", "wp.55"
+"0.00000", "0.00000", "wp.56"
+"0.00000", "0.00000", "wp.57"
+"0.00000", "0.00000", "wp.58"
+"0.00000", "0.00000", "wp.59"
+"0.00000", "0.00000", "wp.60"
+"0.00000", "0.00000", "wp.61"
+"0.00000", "0.00000", "wp.62"
+"0.00000", "0.00000", "wp.63"
+"0.00000", "0.00000", "wp.64"
+"0.00000", "0.00000", "wp.65"
+"0.00000", "0.00000", "wp.66"
+"0.00000", "0.00000", "wp.67"
+"0.00000", "0.00000", "wp.68"
+"0.00000", "0.00000", "wp.69"
+"0.00000", "0.00000", "wp.70"
+"0.00000", "0.00000", "wp.71"
+"0.00000", "0.00000", "wp.72"
+"0.00000", "0.00000", "wp.73"
+"0.00000", "0.00000", "wp.74"
+"0.00000", "0.00000", "wp.75"
+"0.00000", "0.00000", "wp.76"
+"0.00000", "0.00000", "wp.77"
+"0.00000", "0.00000", "wp.78"
+"0.00000", "0.00000", "wp.79"
+"0.00000", "0.00000", "wp.80"
+"0.00000", "0.00000", "wp.81"
+"0.00000", "0.00000", "wp.82"
+"0.00000", "0.00000", "wp.83"
+"0.00000", "0.00000", "wp.84"
+"0.00000", "0.00000", "wp.85"
+"0.00000", "0.00000", "wp.86"
+"0.00000", "0.00000", "wp.87"
+"0.00000", "0.00000", "wp.88"
+"0.00000", "0.00000", "wp.89"
+"0.00000", "0.00000", "wp.90"
+"0.00000", "0.00000", "wp.91"
+"0.00000", "0.00000", "wp.92"
+"0.00000", "0.00000", "wp.93"
+"0.00000", "0.00000", "wp.94"
+"0.00000", "0.00000", "wp.95"
+"0.00000", "0.00000", "wp.96"
+"0.00000", "0.00000", "wp.97"
+"0.00000", "0.00000", "wp.98"
+"0.00000", "0.00000", "wp.99"
+"0.00000", "0.00000", "wp.100"
+"0.00000", "0.00000", "wp.101"
+"0.00000", "0.00000", "wp.102"
+"0.00000", "0.00000", "wp.103"
+"0.00000", "0.00000", "wp.104"
+"0.00000", "0.00000", "wp.105"
+"0.00000", "0.00000", "wp.106"
+"0.00000", "0.00000", "wp.107"
+"0.00000", "0.00000", "wp.108"
+"0.00000", "0.00000", "wp.109"
+"0.00000", "0.00000", "wp.110"
+"0.00000", "0.00000", "wp.111"
+"0.00000", "0.00000", "wp.112"
+"0.00000", "0.00000", "wp.113"
+"0.00000", "0.00000", "wp.114"
+"0.00000", "0.00000", "wp.115"
+"0.00000", "0.00000", "wp.116"
+"0.00000", "0.00000", "wp.117"
+"0.00000", "0.00000", "wp.118"
+"0.00000", "0.00000", "wp.119"
+"0.00000", "0.00000", "wp.120"
+"0.00000", "0.00000", "wp.121"
+"0.00000", "0.00000", "wp.122"
+"0.00000", "0.00000", "wp.123"
+"0.00000", "0.00000", "wp.124"
+"0.00000", "0.00000", "wp.125"
+"0.00000", "0.00000", "wp.126"
+"0.00000", "0.00000", "wp.127"
+"0.00000", "0.00000", "wp.128"
+"0.00000", "0.00000", "wp.129"
+"0.00000", "0.00000", "wp.130"
+"0.00000", "0.00000", "wp.131"
+"0.00000", "0.00000", "wp.132"
+"0.00000", "0.00000", "wp.133"
+"0.00000", "0.00000", "wp.134"
+"0.00000", "0.00000", "wp.135"
+"0.00000", "0.00000", "wp.136"
+"0.00000", "0.00000", "wp.137"
+"0.00000", "0.00000", "wp.138"
+"0.00000", "0.00000", "wp.139"
+"0.00000", "0.00000", "wp.140"
+"0.00000", "0.00000", "wp.141"
+"0.00000", "0.00000", "wp.142"
+"0.00000", "0.00000", "wp.143"
+"0.00000", "0.00000", "wp.144"
+"0.00000", "0.00000", "wp.145"
+"0.00000", "0.00000", "wp.146"
+"0.00000", "0.00000", "wp.147"
+"0.00000", "0.00000", "wp.148"
+"0.00000", "0.00000", "wp.149"
diff --git a/testo.d/mkshort.test b/testo.d/mkshort.test
new file mode 100644 (file)
index 0000000..51007a3
--- /dev/null
@@ -0,0 +1,13 @@
+
+gpsbabel -s -i unicsv -f ${REFERENCE}/mkshort.csv -o xcsv,style=${REFERENCE}/mkshort.style,snlen=6 -F ${TMPDIR}/mkshort6.csv
+compare ${REFERENCE}/mkshort6.csv ${TMPDIR}/mkshort6.csv
+gpsbabel -s -i unicsv -f ${REFERENCE}/mkshort.csv -o xcsv,style=${REFERENCE}/mkshort.style,snlen=5 -F ${TMPDIR}/mkshort5.csv
+compare ${REFERENCE}/mkshort5.csv ${TMPDIR}/mkshort5.csv
+gpsbabel -s -i unicsv -f ${REFERENCE}/mkshort.csv -o xcsv,style=${REFERENCE}/mkshort.style,snlen=4 -F ${TMPDIR}/mkshort4.csv
+compare ${REFERENCE}/mkshort4.csv ${TMPDIR}/mkshort4.csv
+# expected failure: "mkshort failure, the specified short length is insufficient."
+# expecting this to fail so call directly rather than via gpsbabel function
+${VALGRIND} "${PNAME}" -s -i unicsv -f ${REFERENCE}/mkshort.csv -o xcsv,style=${REFERENCE}/mkshort.style,snlen=3 -F ${TMPDIR}/mkshort3.csv > /dev/null 2> ${TMPDIR}/mkshort3.log && {
+  echo "${PNAME} succeeded! (it shouldn't have with this input...)"
+}
+compare ${REFERENCE}/mkshort3.log ${TMPDIR}/mkshort3.log